<template>
	<div id="guide-search" @click.stop="onShowClick" class="header-search" :class="{show: isShow}">
		<svg-icon class-name="search-icon" icon="search"></svg-icon>

		<el-select filterable remote default-first-option :remote-method="querySearch" v-model="search"
			ref="headerSearchSelectRef" class="header-search-select" placeholder="search" @change="onSelectChange">
			<el-option v-for="option in searchOptions" :key="option.item.path" :value="option.item"
				:label="option.item.title.join(' > ')"></el-option>
		</el-select>
	</div>
</template>

<script setup>
	import {
		ref,
		computed,
		watch
	} from 'vue'

	import {
		filterRouters
	} from '@/utils/route'

	import {
		useRouter
	} from 'vue-router'

	import Fuse from 'fuse.js'
	import {
		generateRoutes
	} from './FuseData.js'

	import {
		watchSwitchLang
	} from '@/utils/i18n'

	// 数据源
	const router = useRouter()

	let searchPool = computed(() => {
		const fRoutes = filterRouters(router.getRoutes())
		return generateRoutes(fRoutes)
	})

	// 搜索库相关
	let fuse

	const initFuse = searchPool => {
		fuse = new Fuse(searchPool, {
			// 是否按优先级进行排序
			shouldSort: true,
			// 匹配长度超过这个值的才会被认为是匹配的
			minMatchCharLength: 1,
			// 将被搜索的键列表。 这支持嵌套路径、加权搜索、在字符串和对象数组中搜索。
			// name：搜索的键
			// weight：对应的权重
			keys: [{
					name: 'title',
					weight: 0.7
				},
				{
					name: 'path',
					weight: 0.3
				}
			]
		})
	}

	initFuse(searchPool.value)

	// 控制search展示
	const isShow = ref(false)

	const search = ref('')

	const searchOptions = ref([])

	const onShowClick = () => {
		isShow.value = !isShow.value
	}

	const querySearch = query => {
		if (query !== '') {
			searchOptions.value = fuse.search(query)
		} else {
			searchOptions.value = []
		}
	}

	const onSelectChange = val => {
		router.push(val.path)
	}

	watch(isShow, val => {
		if (val) {
			headerSearchSelectRef.value.focus()
			document.body.addEventListener('click', onClose)
		} else {
			document.body.removeEventListener('click', onClose)
		}
	})

	// 关闭事件
	const headerSearchSelectRef = ref(null)
	const onClose = () => {
		headerSearchSelectRef.value.blur()
		isShow.value = false
		searchOptions.value = []
	}

	watchSwitchLang(() => {
		searchPool = computed(() => {
			const filterRoutes = filterRouters(router.getRoutes())
			return generateRoutes(filterRoutes)
		})
		initFuse(searchPool.value)
	})
</script>

<style lang="scss" scoped>
	.header-search {

		font-size: 0 !important;

		:deep .search-icon {
			cursor: pointer;
			font-size: 18px;
			vertical-align: middle;
		}

		.header-search-select {
			font-size: 18px;
			transition: width 0.2s;
			width: 0;
			overflow: hidden;
			background: transparent;
			border-radius: 0;
			display: inline-block;
			vertical-align: middle;

			:deep .el-input__inner {
				border-radius: 0;
				border: 0;
				padding-left: 0;
				padding-right: 0;
				box-shadow: none !important;
				border-bottom: 1px solid #d9d9d9;
				vertical-align: middle;
			}
		}

		&.show {
			.header-search-select {
				width: 210px;
				margin-left: 10px;
			}
		}
	}
</style>
